Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Commit d30f405fd5b94295a6e93445ea7d108364638787


Parents : 1378a3f
Author : Mark Qvist <mark@unsigned.io>
Date : 2023-02-14T19:46:21+01:00

Added input field data handling

Changes

3 files changed, 119 insertions(+), 53 deletions(-)


Diff

diff --git a/nomadnet/Node.py b/nomadnet/Node.py
index 018d43b..13e1f41 100644
--- a/nomadnet/Node.py
+++ b/nomadnet/Node.py
@@ -97,7 +97,7 @@ class Node:
for directory in directories:
self.scan_files(base_path+"/"+directory)
- def serve_page(self, path, data, request_id, remote_identity, requested_at):
+ def serve_page(self, path, data, request_id, link_id, remote_identity, requested_at):
RNS.log("Page request "+RNS.prettyhexrep(request_id)+" for: "+str(path), RNS.LOG_VERBOSE)
try:
self.app.peer_settings["served_page_requests"] += 1
@@ -152,7 +152,18 @@ class Node:
if request_allowed:
RNS.log("Serving page: "+file_path, RNS.LOG_VERBOSE)
if os.access(file_path, os.X_OK):
- generated = subprocess.run([file_path], stdout=subprocess.PIPE)
+ env_map = {}
+ if link_id != None:
+ env_map["link_id"] = RNS.hexrep(link_id, delimit=False)
+ if remote_identity != None:
+ env_map["remote_identity"] = RNS.hexrep(remote_identity.hash, delimit=False)
+
+ if data != None and isinstance(data, dict):
+ for e in data:
+ if isinstance(e, str) and e.startswith("field_"):
+ env_map[e] = data[e]
+
+ generated = subprocess.run([file_path], stdout=subprocess.PIPE, env=env_map)
return generated.stdout
else:
fh = open(file_path, "rb")

diff --git a/nomadnet/ui/textui/Browser.py b/nomadnet/ui/textui/Browser.py
index 8b75fbd..6c3aa51 100644
--- a/nomadnet/ui/textui/Browser.py
+++ b/nomadnet/ui/textui/Browser.py
@@ -81,6 +81,7 @@ class Browser:
self.aspects = aspects
self.destination_hash = destination_hash
self.path = path
+ self.field_data = None
self.timeout = Browser.DEFAULT_TIMEOUT
self.last_keypress = None
@@ -161,7 +162,31 @@ class Browser:
else:
return destination_type
- def handle_link(self, link_target):
+ def handle_link(self, link_target, link_fields = None):
+ field_data = None
+ if link_fields != None:
+ field_data = {}
+ def recurse_down(w):
+ target = None
+ if isinstance(w, list):
+ for t in w:
+ recurse_down(t)
+ elif isinstance(w, tuple):
+ for t in w:
+ recurse_down(t)
+ elif hasattr(w, "contents"):
+ recurse_down(w.contents)
+ elif hasattr(w, "original_widget"):
+ recurse_down(w.original_widget)
+ elif hasattr(w, "_original_widget"):
+ recurse_down(w._original_widget)
+ else:
+ if hasattr(w, "field_name") and (link_fields == "all" or w.field_name in link_fields):
+ field_data["field_"+w.field_name] = w.get_edit_text()
+
+ recurse_down(self.attr_maps)
+ RNS.log("Found field data: "+str(field_data))
+
components = link_target.split("@")
destination_type = None
@@ -177,7 +202,7 @@ class Browser:
RNS.log("Browser handling link to: "+str(link_target), RNS.LOG_DEBUG)
self.browser_footer = urwid.Text("Opening link to: "+str(link_target))
try:
- self.retrieve_url(link_target)
+ self.retrieve_url(link_target, field_data)
except Exception as e:
self.browser_footer = urwid.Text("Could not open link: "+str(e))
self.frame.contents["footer"] = (self.browser_footer, self.frame.options())
@@ -365,7 +390,7 @@ class Browser:
self.update_display()
- def retrieve_url(self, url):
+ def retrieve_url(self, url, field_data = None):
self.previous_destination_hash = self.destination_hash
self.previous_path = self.path
@@ -418,6 +443,7 @@ class Browser:
else:
self.set_destination_hash(destination_hash)
self.set_path(path)
+ self.set_field_data(field_data)
self.load_page()
def set_destination_hash(self, destination_hash):
@@ -431,6 +457,8 @@ class Browser:
def set_path(self, path):
self.path = path
+ def set_field_data(self, field_data):
+ self.field_data = field_data
def set_timeout(self, timeout):
self.timeout = timeout
@@ -637,7 +665,11 @@ class Browser:
def load_page(self):
- cached = self.get_cached(self.current_url())
+ if self.field_data == None:
+ cached = self.get_cached(self.current_url())
+ else:
+ cached = None
+
if cached:
self.status = Browser.DONE
self.page_data = cached
@@ -671,7 +703,11 @@ class Browser:
page_data = b"The requested local page did not exist in the file system"
if os.path.isfile(page_path):
if os.access(page_path, os.X_OK):
- generated = subprocess.run([page_path], stdout=subprocess.PIPE)
+ if self.field_data != None:
+ env_map = self.field_data
+ else:
+ env_map = None
+ generated = subprocess.run([page_path], stdout=subprocess.PIPE, env=env_map)
page_data = generated.stdout
else:
file = open(page_path, "rb")
@@ -758,7 +794,7 @@ class Browser:
self.update_display()
receipt = self.link.request(
self.path,
- data = None,
+ data = self.field_data,
response_callback = self.response_received,
failed_callback = self.request_failed,
progress_callback = self.response_progressed

diff --git a/nomadnet/ui/textui/MicronParser.py b/nomadnet/ui/textui/MicronParser.py
index fc1a6ec..917808c 100644
--- a/nomadnet/ui/textui/MicronParser.py
+++ b/nomadnet/ui/textui/MicronParser.py
@@ -462,49 +462,52 @@ def make_output(state, line, url_delegate):
state["align"] = state["default_align"]
elif c == "<":
- field_name = None
- field_name_end = line[i:].find("`")
- if field_name_end == -1:
- pass
- else:
- field_name = line[i+1:i+field_name_end]
- field_name_skip = len(field_name)
- field_masked = False
- field_width = 24
-
- if "|" in field_name:
- f_components = field_name.split("|")
- field_flags = f_components[0]
- field_name = f_components[1]
- if "!" in field_flags:
- field_flags = field_flags.replace("!", "")
- field_masked = True
- if len(field_flags) > 0:
- field_width = min(int(field_flags), 256)
-
- def sr():
- return "@{"+str(random.randint(1000,9999))+"}"
- rsg = sr()
- while rsg in line[i+field_name_end:]:
- rsg = sr()
- lr = line[i+field_name_end:].replace("\\>", rsg)
- endpos = lr.find(">")
-
- if endpos == -1:
+ try:
+ field_name = None
+ field_name_end = line[i:].find("`")
+ if field_name_end == -1:
pass
-
else:
- field_data = lr[1:endpos].replace(rsg, "\\>")
- skip = len(field_data)+field_name_skip+2
- field_data = field_data.replace("\\>", ">")
- output.append({
- "type":"field",
- "name": field_name,
- "width": field_width,
- "masked": field_masked,
- "data": field_data,
- "style": make_style(state)
- })
+ field_name = line[i+1:i+field_name_end]
+ field_name_skip = len(field_name)
+ field_masked = False
+ field_width = 24
+
+ if "|" in field_name:
+ f_components = field_name.split("|")
+ field_flags = f_components[0]
+ field_name = f_components[1]
+ if "!" in field_flags:
+ field_flags = field_flags.replace("!", "")
+ field_masked = True
+ if len(field_flags) > 0:
+ field_width = min(int(field_flags), 256)
+
+ def sr():
+ return "@{"+str(random.randint(1000,9999))+"}"
+ rsg = sr()
+ while rsg in line[i+field_name_end:]:
+ rsg = sr()
+ lr = line[i+field_name_end:].replace("\\>", rsg)
+ endpos = lr.find(">")
+
+ if endpos == -1:
+ pass
+
+ else:
+ field_data = lr[1:endpos].replace(rsg, "\\>")
+ skip = len(field_data)+field_name_skip+2
+ field_data = field_data.replace("\\>", ">")
+ output.append({
+ "type":"field",
+ "name": field_name,
+ "width": field_width,
+ "masked": field_masked,
+ "data": field_data,
+ "style": make_style(state)
+ })
+ except Exception as e:
+ pass
elif c == "[":
endpos = line[i:].find("]")
@@ -517,13 +520,20 @@ def make_output(state, line, url_delegate):
link_components = link_data.split("`")
if len(link_components) == 1:
link_label = ""
+ link_fields = ""
link_url = link_data
elif len(link_components) == 2:
link_label = link_components[0]
link_url = link_components[1]
+ link_fields = ""
+ elif len(link_components) == 3:
+ link_label = link_components[0]
+ link_url = link_components[1]
+ link_fields = link_components[2]
else:
link_url = ""
link_label = ""
+ link_fields = ""
if len(link_url) != 0:
if link_label == "":
@@ -551,6 +561,14 @@ def make_output(state, line, url_delegate):
if url_delegate != None:
linkspec = LinkSpec(link_url, orig_spec)
+ if link_fields != "":
+ if link_fields == "*":
+ linkspec.link_fields = "all"
+ else:
+ lf = link_fields.split("|")
+ if len(lf) > 0:
+ linkspec.link_fields = lf
+
output.append((linkspec, link_label))
else:
output.append(make_part(state, link_label))
@@ -593,6 +611,7 @@ def make_output(state, line, url_delegate):
class LinkSpec(urwid.AttrSpec):
def __init__(self, link_target, orig_spec):
self.link_target = link_target
+ self.link_fields = None
urwid.AttrSpec.__init__(self, orig_spec.foreground, orig_spec.background)
@@ -611,9 +630,9 @@ class LinkableText(urwid.Text):
if self.delegate != None:
self.delegate.last_keypress = 0
- def handle_link(self, link_target):
+ def handle_link(self, link_target, link_fields):
if self.delegate != None:
- self.delegate.handle_link(link_target)
+ self.delegate.handle_link(link_target, link_fields)
def find_next_part_pos(self, pos, part_positions):
for position in part_positions:
@@ -671,7 +690,7 @@ class LinkableText(urwid.Text):
item = self.find_item_at_pos(self._cursor_position)
if item != None:
if isinstance(item, LinkSpec):
- self.handle_link(item.link_target)
+ self.handle_link(item.link_target, item.link_fields)
elif key == "up":
self._cursor_position = 0
@@ -761,7 +780,7 @@ class LinkableText(urwid.Text):
if item != None:
if isinstance(item, LinkSpec):
- self.handle_link(item.link_target)
+ self.handle_link(item.link_target, item.link_fields)
self._invalidate()
self._emit("change")


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────